package gormclient

import (
	"errors"
	"fmt"
	"organoid_public/pkg/utils"
	"organoid_public/pkg/valueobject"
	"strings"
	"time"

	"gorm.io/gorm"
)

// BaseModel 基础模型
type BaseModel struct {
	ID        uint           `gorm:"primarykey;autoincrement" json:"id"`
	CreatedAt time.Time      `json:"createdAt"`
	UpdatedAt time.Time      `json:"updatedAt"`
	DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
}

// PageList 分页结果
type PageList[T any] struct {
	Page     int    `json:"page"`
	PageSize int    `json:"pageSize"`
	Total    uint64 `json:"total"`
	List     []T    `json:"list"`
}

const (
	// DefaultPageSize 默认页大小
	DefaultPageSize uint = 10
)

// GetPageList 分页查询
func GetPageList[T any](db *gorm.DB, pagination *valueobject.Pagination) (*PageList[T], error) {
	var (
		total int64
		err   error
		res   PageList[T]
		model []T
	)
	err = db.Model(&model).Count(&total).Error
	if err != nil {
		return &res, err
	}

	err = db.Offset(pagination.GetOffset()).Limit(pagination.GetPageSize()).Find(&model).Error
	if err != nil {
		return &res, err
	}

	res.Page = pagination.GetPage()
	res.PageSize = pagination.GetPageSize()
	res.Total = uint64(total)
	res.List = model
	return &res, nil
}

// DataExist 判断值是否已经存在
func DataExist(db *gorm.DB, model interface{}) (bool, error) {
	var (
		err error
	)
	err = db.First(model).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return true, nil
}

// GenerateUniqueCode 生成全表唯一编码
func GenerateUniqueCode(db *gorm.DB, model interface{}, prefix, field string, length, repeat int) (string, error) {
	var (
		err  error
		code string
	)

	if repeat >= 5 {
		return "", errors.New("系统错误,请刷新后重试")
	}

	code, err = utils.RandomAlphaString(length)
	if err != nil {
		return "", err
	}

	err = db.Where(field+" = ?", prefix+code).First(model).Error
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		return code, nil
	}
	return GenerateUniqueCode(db, model, prefix, field, length, repeat+1)
}

// GetFirst 单条查询
func GetFirst(db *gorm.DB, model interface{}, conditionArr ...interface{}) error {
	err := db.First(model, conditionArr...).Error
	if err != nil {
		return err
	}
	return nil
}

// GetFirstWithError 单条查询带错误
func GetFirstWithError(db *gorm.DB, model interface{}, resError error, conditionArr ...interface{}) error {
	err := db.First(model, conditionArr...).Error
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		return resError
	} else if err != nil {
		return err
	}
	return nil
}

// Find 多条数据查询
func Find(db *gorm.DB, model interface{}, conditionArr ...interface{}) error {
	err := db.Model(model).Find(model, conditionArr).Error
	if err != nil {
		return err
	}
	return nil
}

// GetColumn 查询单列数据
func GetColumn(db *gorm.DB, model interface{}, colName string, col interface{}) error {
	err := db.Model(model).Pluck(colName, &col).Error
	if err != nil {
		return err
	}
	return nil
}

// MultiWhereOrFindInSet 批量使用or find in set进行查询
func MultiWhereOrFindInSet(db *gorm.DB, columnName, columnStr string) *gorm.DB {
	columnStrSlice := strings.Split(columnStr, ",")
	where := ""
	for _, c := range columnStrSlice {
		if where != "" {
			where += " or "
		}
		where = where + fmt.Sprintf("FIND_IN_SET(%s, REPLACE(%s, ' ', ''))", "\""+c+"\"", columnName)
	}
	return db.Where(where)
}
